package org.aeon.client.view.components;

import lombok.extern.slf4j.Slf4j;
import org.aeon.client.context.GlobalContext;
import org.aeon.client.view.AccountUI;
import org.aeon.client.view.ApplicationUI;
import org.aeon.client.view.components.menuPanel.PopupPrompt;
import org.aeon.client.view.components.textField.MPasswordField;
import org.aeon.client.view.components.textField.MTextField;
import org.aeon.entity.dto.UserVerificationDto;
import org.aeon.message.request.CancelLoginRequestMessage;
import org.aeon.message.request.LoginRequestMessage;
import org.aeon.utils.ImageSetUtil;
import org.aeon.utils.SimpleRequestUtil;
import org.aeon.utils.SwingUtil;

import javax.swing.*;
import java.awt.*;

import static org.aeon.client.context.MessageMap.MessageContextKey.LoginMessage;


/**
 * @author: MissingAeon
 * @date: 2024/2/21 16:22
 * @description:
 */
@Slf4j
public class LoginPanel extends JPanel {
    private final JButton loginBut;
    private final MPasswordField passwordField;
    private final JLabel loginLabel;
    private final MTextField usernameField;

    public LoginPanel(JPanel parentPanel) {
        this.setLayout(new GridLayout(1, 2));

        final JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
        panel.setBorder(BorderFactory.createEmptyBorder(70, 10, 20, 10));

        final JLabel title = new JLabel("登陆");
        title.setAlignmentX(Component.CENTER_ALIGNMENT);
        title.setFont(new Font("黑体", Font.BOLD, 24));
        panel.add(title);

        panel.add(Box.createVerticalStrut(25));

        final Dimension preferredSize = new Dimension(250, 35);
        final ImageIcon imageIcon = new ImageIcon(ImageSetUtil.getImage("warning", 30, 30));

        final Box usernameBox = Box.createHorizontalBox();
        usernameBox.add(Box.createHorizontalStrut(45));
        usernameField = new MTextField("账号");
        usernameField.setText("h");
        SwingUtil.setSize(usernameField, preferredSize);
        usernameBox.add(usernameField);

        usernameBox.add(Box.createHorizontalStrut(10));
        final JLabel usernameWarning = new JLabel(imageIcon);
        usernameWarning.setVisible(false);
        usernameBox.add(usernameWarning);
        usernameBox.add(Box.createHorizontalGlue());
        panel.add(usernameBox);

        panel.add(Box.createVerticalStrut(15));

        final Box passwordBox = Box.createHorizontalBox();
        passwordBox.add(Box.createHorizontalStrut(45));
        passwordField = new MPasswordField("密码");
        passwordField.setText("h");
        passwordField.setPreferredSize(preferredSize);
        passwordField.setMaximumSize(preferredSize);
        passwordField.setMinimumSize(preferredSize);
        passwordBox.add(passwordField);
        passwordBox.add(Box.createHorizontalStrut(10));
        final JLabel passwordWarning = new JLabel(imageIcon);
        passwordWarning.setVisible(false);
        passwordBox.add(passwordWarning);
        passwordBox.add(Box.createHorizontalGlue());
        panel.add(passwordBox);

        panel.add(Box.createVerticalStrut(15));

        final JCheckBox checkBox = new JCheckBox("记住密码");
        checkBox.setAlignmentX(Component.LEFT_ALIGNMENT);
        panel.add(checkBox);

        panel.add(Box.createVerticalStrut(20));

        loginBut = new JButton("登陆");
        final Dimension dimensionBut = new Dimension(160, 30);
        SwingUtil.setSize(loginBut, dimensionBut);
        loginBut.setContentAreaFilled(false);
        loginBut.setAlignmentX(Component.CENTER_ALIGNMENT);
        panel.add(loginBut);

        panel.add(Box.createVerticalStrut(70));

        loginLabel = new JLabel("这是个登陆提示");
        loginLabel.setForeground(new Color(0x0FFFFFF, true));
        loginLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
        panel.add(loginLabel);

        panel.add(Box.createVerticalStrut(12));

        final JPanel tmpP = new JPanel();
        tmpP.setLayout(new BoxLayout(tmpP, BoxLayout.X_AXIS));
        tmpP.add(Box.createHorizontalGlue());
        final JButton registerBut = new JButton("注册→");
        registerBut.setAlignmentX(Component.LEFT_ALIGNMENT);
        registerBut.setContentAreaFilled(false);
        tmpP.add(registerBut);

        panel.add(tmpP);
        this.add(panel);

        this.add(AccountUI.logPanel());


        registerBut.addActionListener(e -> {
            final CardLayout layout = (CardLayout) parentPanel.getLayout();
            layout.show(parentPanel, "RP");
            parentPanel.repaint();
        });

        loginBut.addActionListener(e -> {
            loginBut.setEnabled(false);
            usernameWarning.setVisible(false);
            passwordWarning.setVisible(false);

            String username = usernameField.getText();
            String password = new String(passwordField.getPassword());

            if (username == null || username.isEmpty()) {
                showWarning(usernameWarning, "请输入用户名！");
                return;
            }
            if (password.isEmpty()) {
                showWarning(passwordWarning, "请输入密码！");
                return;
            }
            clearFields();
            GlobalContext context = GlobalContext.getContext();
            if (context.getChannel() != null) {
                SimpleRequestUtil.sendAndWaitOrTimeout(context, new LoginRequestMessage(new UserVerificationDto(username, password)),
                        this::handleLoginSuccess, () -> {
                            loginBut.setEnabled(true);
                            SimpleRequestUtil.send(context, new CancelLoginRequestMessage());
                        }, 10);
            } else setErrorMessage("无法连接到服务器");
        });
    }

    public static Timer successFuture(JPanel panel) {
        final Timer timer = new Timer(1500, (event) -> {
            // 创建应用窗口
            new ApplicationUI().setVisible(true);
            PopupPrompt.createPopUp("欢迎回来，" + GlobalContext.getContext().getCurrentUser().getNickname());
            // 关闭登陆窗口
            Window window = SwingUtilities.getWindowAncestor(panel);
            if (window instanceof JFrame frame) {
                frame.setVisible(false);
                frame.dispose();
            }
        });
        timer.setRepeats(false);
        return timer;
    }

    private void showWarning(JLabel warningLabel, String message) {
        warningLabel.setToolTipText(message);
        warningLabel.setVisible(true);
        loginBut.setEnabled(true);
    }

    private void clearFields() {
        usernameField.setText("");
        passwordField.setText("");
    }

    private void handleLoginSuccess() {
        SwingUtilities.invokeLater(() -> {
            final GlobalContext context = GlobalContext.getContext();
            final String loginMessage = context.getMessageMap().del(LoginMessage);
            if (context.getIsLogin().get()) {
                loginLabel.setText(loginMessage);
                loginLabel.setForeground(new Color(0x414141));
                LoginPanel.successFuture(this).start();
            } else {
                setErrorMessage(loginMessage);
            }
        });
    }

    private void setErrorMessage(String message) {
        SwingUtilities.invokeLater(() -> {
            loginLabel.setText(message);
            loginLabel.setForeground(new Color(0xFF1616));
            loginBut.setEnabled(true);
        });
    }
}
